﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AgileTimeTracker.Client.Wpf.Common;
using AgileTimeTracker.Client.Wpf.Services;
using AgileTimeTracker.Domain.Exceptions;
using AgileTimeTracker.Domain.TaskModule;
using Cwi.Utils;

namespace AgileTimeTracker.Client.Wpf.TimeControlModule
{
    public class EditTaskViewModel : PageViewModel
    {
        #region Fields

        private TfsTask tfsTask;

        private string tfsWorkItemId;
        private string taskTitle;
        private string userStory;
        private string iterationPath;
        private double estimatedWork;
        private double remainingWork;
        private double completedWork;

        #endregion // Fields

        public EditTaskViewModel()
        {
            this.Title = "New Task";
        }

        public EditTaskViewModel(TfsTask tfsTask)
        {
            this.Title = "Edit Task";
            this.Refresh(tfsTask);
        }

        #region Properties

        public int TfsId
        {
            get
            {
                var tfsId = 0;
                int.TryParse(this.tfsWorkItemId, out tfsId);
                return tfsId;
            }
        }

        public double EstimatedWork
        {
            get { return this.estimatedWork; }
            set { this.OnPropertyChanged(ref this.estimatedWork, value); }
        }

        public double RemainingWork
        {
            get { return this.remainingWork; }
            set { this.OnPropertyChanged(ref this.remainingWork, value); }
        }

        public double CompletedWork
        {
            get { return this.completedWork; }
            set { this.OnPropertyChanged(ref this.completedWork, value); }
        }

        public TfsTask CurrentTask
        {
            get { return this.tfsTask; }
        }

        public string TfsWorkItemId
        {
            get { return this.tfsWorkItemId; }
            set { this.OnPropertyChanged(ref this.tfsWorkItemId, value); }
        }

        public string TaskTitle
        {
            get { return this.taskTitle; }
            set { this.OnPropertyChanged(ref this.taskTitle, value); }
        }

        public string UserStory
        {
            get { return this.userStory; }
            set { this.OnPropertyChanged(ref this.userStory, value); }
        }

        public string IterationPath
        {
            get { return this.iterationPath; }
            set { this.OnPropertyChanged(ref this.iterationPath, value); }
        }

        #endregion // Properties

        public void Refresh(TfsTask tfsTask)
        {
            this.tfsTask = Check.NotNull(tfsTask, "tfsTask");
            this.TfsWorkItemId = this.tfsTask.TfsWorkItemId.HasValue ? this.tfsTask.TfsWorkItemId.Value.ToString() : string.Empty;
            this.TaskTitle = this.tfsTask.Title;
            this.IterationPath = this.tfsTask.IterationPath;
            this.UserStory = this.tfsTask.UserStory;
            this.EstimatedWork = this.tfsTask.EstimatedWork;
            this.RemainingWork = this.tfsTask.RemainingWork;
            this.CompletedWork = this.tfsTask.CompletedWork;
        }

        #region Commands

        public RelayCommand SaveCommand { get; set; }

        public void Save()
        {
            var validationErrors = new List<ValidationError>();
            validationErrors.CheckRequired(this.taskTitle, "Title", "Title");
            validationErrors.IsValidOrThrow();
            if (this.tfsTask == null)
            {
                this.tfsTask = new TfsTask();
                MainWindowViewModel.Instance.CurrentProject.TfsTasks.Add(tfsTask);
            }

            var tfsId = this.TfsId;

            this.tfsTask.Title = this.taskTitle;
            this.tfsTask.TfsWorkItemId = tfsId == 0 ? (int?)null : tfsId;
            this.tfsTask.UserStory = this.userStory;
            this.tfsTask.IterationPath = this.iterationPath;
            this.tfsTask.RemainingWork = this.remainingWork;
            this.tfsTask.EstimatedWork = this.estimatedWork;
            this.tfsTask.CompletedWork = this.completedWork;

            this.BlockUi("Saving...");

            Task.Run(() =>
            {
                AppService.Instance.SaveUser(MainWindowViewModel.Instance.CurrentUser);
                AppService.Instance.SafeTfsWorkItem(MainWindowViewModel.Instance.CurrentProject, this.CurrentTask);
            }).ContinueWith(t =>
            {
                this.UnblockUi();
                this.Close();
            });                       
        }

        public RelayCommand UpdateFromTfsCommand { get; set; }

        public void UpdateFromTfs()
        {            
            if (this.TfsId == 0)
            {
                return;
            }

            this.BlockUi();

            Task.Run(() =>
            {
                var tfsWorkItem = AppService.Instance.GetTfsWorkItem(MainWindowViewModel.Instance.CurrentProject, this.TfsId);                
                return tfsWorkItem;
            }).ContinueWith(r =>
            {
                var tfsWorkItem = r.Result;
                this.TaskTitle = tfsWorkItem.Title;
                this.UserStory = tfsWorkItem.UserStory;
                this.IterationPath = tfsWorkItem.IterationPath;
                this.EstimatedWork = tfsWorkItem.OriginalEstimate;
                this.RemainingWork = tfsWorkItem.RemainingWork;
                this.CompletedWork = tfsWorkItem.CompletedWork;
                this.UnblockUi();
            });
        }        

        #endregion // Commands

        protected override void InititalizeCommands()
        {
            base.InititalizeCommands();
            this.SaveCommand = new RelayCommand(this.Save);
            this.UpdateFromTfsCommand = new RelayCommand(UpdateFromTfs);
        }        
    }
}
